package com.th.supcom.pds.impl.service.internal;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.carefx.fc.framework.web.gwt.util.FcUtils;
import net.carefx.framework.exception.BusinessException;
import net.carefx.framework.translate.TranslatorManager;
import net.carefx.framework.util.ConvertUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import com.th.supcom.pds.domain.pojo.PdsSupply;
import com.th.supcom.pds.domain.pojo.PdsSupplyDetail;
import com.th.supcom.pds.domain.pojo.PdsSupplyPro;
import com.th.supcom.pds.domain.vo.PatientInfo;
import com.th.supcom.pds.domain.vo.PdsSupplyDetailVO;
import com.th.supcom.pds.domain.vo.PdsSupplyResultSet;
import com.th.supcom.pds.domain.vo.PdsSupplyVO;
import com.th.supcom.pds.impl.common.enums.PrescSource;
import com.th.supcom.pds.impl.common.enums.SendOrReturnEnum;
import com.th.supcom.pds.impl.manager.PdsSupplyDetailManager;
import com.th.supcom.pds.impl.manager.PdsSupplyManager;
import com.th.supcom.pds.impl.manager.PdsSupplyProManager;
import com.th.supcom.pds.internal.api.OutDrugReturnApplyService;
import com.th.supcom.pds.medicare.api.AdapterBMSChargeService;
import com.th.supcom.pds.medicare.api.AdapterDrugManagerService;
import com.th.supcom.pds.medicare.api.AdapterPtsExtOutPatientVisitService;

/**
 * @author yzhang
 */
public class OutDrugReturnApplyServiceImpl implements OutDrugReturnApplyService
{
    /** 翻译器 */
    private TranslatorManager m_translatorManager;
    private AdapterPtsExtOutPatientVisitService m_adapterPtsExtOutPatientVisitService;
    private AdapterBMSChargeService m_adapterBMSChargeService;
    private AdapterDrugManagerService m_adapterDrugManagerService;
    private PdsSupplyManager m_pdsSupplyManager;
    private PdsSupplyDetailManager m_pdsSupplyDetailManager;
    private PdsSupplyProManager m_pdsSupplyProManager;

    /** 日志记录器. */
    public static final Logger s_logger = LoggerFactory.getLogger (OutDrugReturnApplyServiceImpl.class);

    @Override
    public List <PdsSupplyResultSet> findOutDrugReturnInfo (Map <String, Object> searchMap)
    {

        List <PdsSupplyResultSet> pdsSupplyResultSets;
        String patientId = (String) searchMap.get ("patientId");
        String prescNo = (String) searchMap.get ("prescNo");
        s_logger.debug ("进入findOutDrugReturnInfo,参数patientId:{},prescNo:{}", new Object[]
        { patientId, prescNo });
        try
        {
            pdsSupplyResultSets = m_adapterBMSChargeService.findOutpReturnChargeItem (searchMap);
        }
        catch (Exception e)
        {
            s_logger.error ("调用门诊可退药品查询接口异常:patientId:{},prescNo:{}", new Object[]
            { patientId, prescNo, e });
            throw new BusinessException ("调用门诊可退药品查询接口异常:" + e.getMessage (), e);
        }
        if (CollectionUtils.isEmpty (pdsSupplyResultSets))
        {
            throw new BusinessException ("查询不到相关药品信息！请重试！");
        }
        getSupplyDetailByOldId (pdsSupplyResultSets);

        setPatientInfo (searchMap, pdsSupplyResultSets, patientId, prescNo);
        return pdsSupplyResultSets;
    }

    private void setPatientInfo (Map <String, Object> searchMap, List <PdsSupplyResultSet> pdsSupplyResultSets, String patientId, String prescNo)
    {
        if (patientId == null && prescNo != null)
        {
            setPatientIdAndPrescSourceByPrescNo (prescNo, searchMap);
        }
        PatientInfo patientInfo;
        try
        {
            patientInfo = m_adapterPtsExtOutPatientVisitService.getPatientInfo (null, PrescSource.OutPatient.getEnumCode (), (String) searchMap.get ("patientId"));
        }
        catch (Exception e1)
        {
            s_logger.error ("调用患者查询服务接口出现异常！patientId:{}", new Object[]
            { patientId, e1 });
            throw new BusinessException ("调用患者信息查询服务出现异常！" + e1.getMessage ());
        }
        if (patientInfo == null)
        {
            s_logger.error ("找不到患者相关信息！请检查参数是否正确！patientId:{}", new Object[]
            { patientId });
            throw new BusinessException ("找不到患者相关信息！请检查参数是否正确！");
        }
        if (pdsSupplyResultSets.size () > 0)
        {
            pdsSupplyResultSets.get (0).setPatientInfo (patientInfo);
        }
    }

    @Override
    public void saveDrugReturnInfo (PdsSupplyResultSet pdsSupplyResultSet)
    {
        s_logger.debug ("开始调用申请退药接口！参数pdsSupply:{},pdsSupplyDetail:{},operatorCode:{},operatorName:{}", new Object[]
        { pdsSupplyResultSet.getPdsSupplyVO (), pdsSupplyResultSet.getPdsSupplyDetailVOs (), pdsSupplyResultSet.getOperatorCode (), pdsSupplyResultSet.getOperatorName () });
        s_logger.debug ("调用进销存入库接口！");
        String exNo;
        try
        {
            exNo = m_adapterDrugManagerService.outpDrugStockIn (pdsSupplyResultSet);
        }
        catch (Exception e)
        {
            s_logger.error ("调用出入库接口时发生异常", new Object[]
            { e });
            throw new BusinessException ("调用出入库接口时发生异常：" + e.getMessage (), e);
        }
        try
        {
            s_logger.debug ("开始保存退药数据！exNo:{}", new Object[]
            { exNo });
            Long supplyId = saveSupplyInfo (pdsSupplyResultSet);
            Long supplyProId = saveSupplyProInfo (pdsSupplyResultSet, supplyId, exNo);
            saveSupplyDetailInfo (pdsSupplyResultSet, supplyId, supplyProId);
        }
        catch (Exception e)
        {
            s_logger.error ("保存退药记录时发生异常：", new Object[]
            { e });
            throw new BusinessException ("保存退药记录时发生异常：" + e.getMessage (), e);
        }
        try
        {
            m_adapterBMSChargeService.OutDrugReturnApply (pdsSupplyResultSet.getPdsSupplyDetailVOs ());
        }
        catch (Exception e)
        {
            s_logger.error ("申请退费时发生异常", new Object[]
            { e });
            throw new BusinessException ("申请退费时发生异常：" + e.getMessage (), e);
        }
    }

    private Long saveSupplyInfo (PdsSupplyResultSet pdsSupplyResultSet)
    {
        PdsSupply pdsSupply = ConvertUtils.convert (PdsSupply.class, pdsSupplyResultSet.getPdsSupplyVO ());
        pdsSupply.setSendOrReturnFlag (SendOrReturnEnum.Return.getCode ());
        return m_pdsSupplyManager.addPdsSupply (pdsSupply);

    }

    /**
     * 通过处方号获取患者ID
     * 
     * @param prescNo
     * @return
     */
    private void setPatientIdAndPrescSourceByPrescNo (String prescNo, Map <String, Object> searchMap)
    {
        Map <String, Object> map = new HashMap <String, Object> ();
        map.put ("prescNo", prescNo);
        map.put ("SendOrReturn", SendOrReturnEnum.Send.getCode ());
        List <PdsSupply> pdsSupplies = m_pdsSupplyManager.findPdsSupplyListByMap (map);
        if (CollectionUtils.isEmpty (pdsSupplies))
        {
            s_logger.error ("输入的处方号找不到相关信息！prescNo:{}", new Object[]
            { prescNo });
            throw new BusinessException ("输入的处方号找不到相关信息！请检查是否输入正确！");
        }
        if (pdsSupplies.size () > 1)
        {
            s_logger.error ("数据异常，处方号存在多条记录！prescNo:{}", new Object[]
            { prescNo });
            throw new BusinessException ("数据异常，处方号存在多条记录！");
        }
        searchMap.put ("patientId", pdsSupplies.get (0).getPatientId ());
        searchMap.put ("prescSource", pdsSupplies.get (0).getPrescSource ());
    }

    /**
     * @param resultSet
     * @param supplyId
     * @param exNo 入库单号
     */
    private Long saveSupplyProInfo (PdsSupplyResultSet resultSet, Long supplyId, String exNo)
    {
        PdsSupplyPro pdsSupplyPro = new PdsSupplyPro ();
        pdsSupplyPro.setSupplyId (supplyId);
        pdsSupplyPro.setPrescNo (resultSet.getPdsSupplyVO ().getPrescNo ());
        pdsSupplyPro.setExNo (exNo);
        pdsSupplyPro.setDrugNameReturn (resultSet.getOperatorName ());
        pdsSupplyPro.setDrugIdReturn (resultSet.getOperatorCode ());
        pdsSupplyPro.setDrugReturnTime (FcUtils.getCurrentServerDateTimeForServer ());
        // 更新原纪录过程的退药信息
        PdsSupplyPro pdsSupplyPro2 = new PdsSupplyPro ();
        pdsSupplyPro2.setSupplyId (resultSet.getPdsSupplyVO ().getSupplyId ());
        pdsSupplyPro2.setDrugNameReturn (resultSet.getOperatorName ());
        pdsSupplyPro2.setDrugIdReturn (resultSet.getOperatorCode ());
        pdsSupplyPro2.setDrugReturnTime (FcUtils.getCurrentServerDateTimeForServer ());
        m_pdsSupplyProManager.modifyPdsSupplyProBySupplyId (pdsSupplyPro2);

        return m_pdsSupplyProManager.addPdsSupplyPro (pdsSupplyPro);
    }

    private void saveSupplyDetailInfo (PdsSupplyResultSet resultSet, Long supplyId, Long supplyProId)
    {
        List <PdsSupplyDetailVO> supplyDetailVOs = resultSet.getPdsSupplyDetailVOs ();
        for (PdsSupplyDetailVO pdsSupplyDetailVO : supplyDetailVOs)
        {
            pdsSupplyDetailVO.setUnitQty (pdsSupplyDetailVO.getReturnQty ());
            Double baseQty = pdsSupplyDetailVO.getReturnQty () * pdsSupplyDetailVO.getFactor ();
            pdsSupplyDetailVO.setQtySum (baseQty);
            pdsSupplyDetailVO.setCosts (pdsSupplyDetailVO.getUnitQty () * pdsSupplyDetailVO.getPackagePrice ());
            pdsSupplyDetailVO.setSupplyId (supplyId);
            pdsSupplyDetailVO.setProId (supplyProId);
            m_pdsSupplyDetailManager.addPdsSupplyDetail (pdsSupplyDetailVO);
        }
    }

    /**
     * 通过原明细ID查询明细的详细信息
     * 
     * @param pdsSupplyResultSets
     */
    private void getSupplyDetailByOldId (List <PdsSupplyResultSet> pdsSupplyResultSets)
    {
        for (PdsSupplyResultSet pdsSupplyResultSet : pdsSupplyResultSets)
        {
            // 供药单总费用
            Double totalSum = 0.0;
            Map <String, Object> supplyMap = new HashMap <String, Object> ();
            supplyMap.put ("prescNo", pdsSupplyResultSet.getPdsSupplyVO ().getPrescNo ());
            supplyMap.put ("sendOrReturnFlag", SendOrReturnEnum.Send.getCode ());
            List <PdsSupply> pdsSupplys = m_pdsSupplyManager.findPdsSupplyListByMap (supplyMap);
            if (CollectionUtils.isEmpty (pdsSupplys) || pdsSupplys.size () > 1)
            {
                s_logger.error ("数据异常，计费信息中可退药品明细对应处方号找不到对应的供药信息或存在多条记录！参数prescNo:{}", new Object[]
                { supplyMap.get ("prescNo") });
                throw new BusinessException ("数据异常，计费信息中可退药品明细对应处方号找不到对应的供药信息或存在多条记录！");
            }
            PdsSupply pdsSupply = m_translatorManager.translate (pdsSupplys.get (0));
            PdsSupplyVO pdsSupplyVO = pdsSupplyResultSet.getPdsSupplyVO ();
            pdsSupplyVO.setSupplyId (pdsSupply.getSupplyId ());
            pdsSupplyVO.setOutpVisitId (pdsSupply.getOutpVisitId ());
            pdsSupplyVO.setPatientId (pdsSupply.getPatientId ());
            pdsSupplyVO.setVisitId (pdsSupply.getVisitId ());
            pdsSupplyVO.setPatiName (pdsSupply.getPatiName ());
            pdsSupplyVO.setPatiSex (pdsSupply.getPatiSex ());
            pdsSupplyVO.setPrescSource (pdsSupply.getPrescSource ());
            pdsSupplyVO.setPrescSourceName (pdsSupply.getPrescSourceName ());
            pdsSupplyVO.setSendOrReturnFlag (SendOrReturnEnum.Return.getCode ());
            pdsSupplyVO.setOrderedBy (pdsSupply.getOrderedBy ());
            pdsSupplyVO.setOrderedByName (pdsSupply.getOrderedByName ());
            pdsSupplyVO.setOrgIdExec (pdsSupply.getOrgIdExec ());
            pdsSupplyVO.setOrgIdExecName (pdsSupply.getOrgIdExecName ());
            List <PdsSupplyDetailVO> pdsSupplyDetailVOs = pdsSupplyResultSet.getPdsSupplyDetailVOs ();
            for (PdsSupplyDetailVO pdsSupplyDetailVO : pdsSupplyDetailVOs)
            {
                Map <String, Object> detailMap = new HashMap <String, Object> ();
                detailMap.put ("prescNo", pdsSupplyDetailVO.getPrescNo ());
                detailMap.put ("supplyDetailId", pdsSupplyDetailVO.getOldSupplyDetailId ());
                // 供药明细单总费用
                Double sum = 0.0;
                List <PdsSupplyDetail> pdsSupplyDetailList = m_pdsSupplyDetailManager.findPdsSupplyDetailListByMap (detailMap);
                if (CollectionUtils.isEmpty (pdsSupplyDetailList) || pdsSupplyDetailList.size () > 1)
                {
                    s_logger.error ("数据异常，计费信息中可退药品明细记录找不到对应的供药信息或存在多条记录！参数prescNo:{}", new Object[]
                    { supplyMap.get ("prescNo") });
                    throw new BusinessException ("数据异常！计费信息中可退药品明细记录找不到对应的供药信息或存在多条记录！");
                }
                PdsSupplyDetail pdsSupplyDetail = m_translatorManager.translate (pdsSupplyDetailList.get (0));
                pdsSupplyDetailVO.setOrderId (pdsSupplyDetail.getOrderId ());
                pdsSupplyDetailVO.setOrderItemDetailId (pdsSupplyDetail.getOrderItemDetailId ());
                pdsSupplyDetailVO.setIsSt (pdsSupplyDetail.getIsSt ());
                pdsSupplyDetailVO.setInfusionFlag (pdsSupplyDetail.getInfusionFlag ());
                pdsSupplyDetailVO.setPivas (pdsSupplyDetail.getPivas ());
                pdsSupplyDetailVO.setPhamType (pdsSupplyDetail.getPhamType ());
                pdsSupplyDetailVO.setPhamStdCode (pdsSupplyDetail.getPhamStdCode ());
                pdsSupplyDetailVO.setPhamName (pdsSupplyDetail.getPhamName ());
                pdsSupplyDetailVO.setPhamSpec (pdsSupplyDetail.getPhamSpec ());
                pdsSupplyDetailVO.setPerMedQty (pdsSupplyDetail.getPerMedQty ());
                pdsSupplyDetailVO.setToxicologyProperty (pdsSupplyDetail.getToxicologyProperty ());
                pdsSupplyDetailVO.setHerbDecoct (pdsSupplyDetail.getHerbDecoct ());
                pdsSupplyDetailVO.setMedUnit (pdsSupplyDetail.getMedUnit ());
                pdsSupplyDetailVO.setUsageCod (pdsSupplyDetail.getUsageCod ());
                pdsSupplyDetailVO.setFreqCode (pdsSupplyDetail.getFreqTimeQty ());
                pdsSupplyDetailVO.setPackageUnit (pdsSupplyDetail.getPackageUnit ());
                pdsSupplyDetailVO.setPackagePrice (pdsSupplyDetail.getPackagePrice ());
                pdsSupplyDetailVO.setPackageUnitName (pdsSupplyDetail.getPackageUnitName ());
                pdsSupplyDetailVO.setFactor (pdsSupplyDetail.getFactor ());
                pdsSupplyDetailVO.setQtyUnit (pdsSupplyDetail.getQtyUnit ());
                pdsSupplyDetailVO.setDurationUnit (pdsSupplyDetail.getDurationUnit ());
                pdsSupplyDetailVO.setIsGroupOrder (pdsSupplyDetail.getIsGroupOrder ());
                pdsSupplyDetailVO.setSortNumber (pdsSupplyDetail.getSortNumber ());
                pdsSupplyDetailVO.setTradeCosts (pdsSupplyDetail.getTradeCosts ());
                pdsSupplyDetailVO.setOfficialDrugLevel (pdsSupplyDetail.getOfficialDrugLevel ());
                pdsSupplyDetailVO.setReceiptDate (pdsSupplyDetail.getReceiptDate ());
                pdsSupplyDetailVO.setPhamBatchNumber (pdsSupplyDetail.getPhamBatchNumber ());
                pdsSupplyDetailVO.setPerformedBy (pdsSupplyDetail.getPerformedBy ());
                pdsSupplyDetailVO.setPerformedByName (pdsSupplyDetail.getPerformedByName ());
                sum = pdsSupplyDetail.getPackagePrice () * pdsSupplyDetailVO.getUnitQty ();
                pdsSupplyDetailVO.setCosts (sum);
                totalSum += sum;
            }
            pdsSupplyVO.setAmountSuggest (totalSum);
        }
    }

    public void setAdapterBMSChargeService (AdapterBMSChargeService adapterBMSChargeService)
    {
        m_adapterBMSChargeService = adapterBMSChargeService;
    }

    public void setTranslatorManager (TranslatorManager translatorManager)
    {
        m_translatorManager = translatorManager;
    }

    public void setPdsSupplyManager (PdsSupplyManager pdsSupplyManager)
    {
        m_pdsSupplyManager = pdsSupplyManager;
    }

    public void setPdsSupplyDetailManager (PdsSupplyDetailManager pdsSupplyDetailManager)
    {
        m_pdsSupplyDetailManager = pdsSupplyDetailManager;
    }

    public void setPdsSupplyProManager (PdsSupplyProManager pdsSupplyProManager)
    {
        m_pdsSupplyProManager = pdsSupplyProManager;
    }

    public void setAdapterDrugManagerService (AdapterDrugManagerService adapterDrugManagerService)
    {
        m_adapterDrugManagerService = adapterDrugManagerService;
    }

    public void setAdapterPtsExtOutPatientVisitService (AdapterPtsExtOutPatientVisitService adapterPtsExtOutPatientVisitService)
    {
        m_adapterPtsExtOutPatientVisitService = adapterPtsExtOutPatientVisitService;
    }

}
